﻿//© 2010-2011 mOcean Mobile. A subsidiary of Mojiva, Inc. All Rights Reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Threading;
using System.Windows.Forms;

namespace mOceanWindows
{
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public class OrmmaBridge
    {

        protected AdViewControl _control = null;
        protected AdViewControl _expandedControl = null;
        protected Size _originalSize;
        protected String _assetUrl, _assetAlias;

        public AdViewControl ParentControl
        {
            set
            {
                _control = value;
                _originalSize = _control.Size;
            }
            get
            {
                return _control;
            }
        }

        private int [] getJsonIntegers( String value )
        {
            value = value.Replace("[", "").Replace("]","");
            value = value.Replace("{", "").Replace("}", "");

            String[] arr = value.Split(',');

            List<int> intList = new List<int>();

            for (int f = 0; f < arr.Length; f++)
            {
                String val = arr[f];
                if (val.Contains(":"))
                {
                    int idx = val.IndexOf(":");
                    val = val.Remove(0, idx + 1);
                    val = val.Replace("\"", "");
                }
                int res;
                if (int.TryParse( val, out res ))
                    intList.Add(res);
            }

            return intList.ToArray();
        }

        private String[] getJsonStrings(String value)
        {
            return value.Replace("[", "").Replace("]", "").Replace("}","").Replace("{","").Split(',');
        }

        #region "Level-1 methods"
        public void expand(String dimensions, String URL, object properties)
        {
            int [] pars = getJsonIntegers(dimensions);

            if (pars.Length >= 4)
            {
                _expandedControl = new AdViewControl();
                _expandedControl.CreateControl();
                _control.Parent.Controls.Add(_expandedControl);
                _expandedControl.Location = new Point(pars[0], pars[1]);
                _expandedControl.Size = new Size(pars[2], pars[3]);
                _expandedControl.Expanded = true;
                _expandedControl.ExpandedURL = URL;
                _expandedControl.Show();
                _expandedControl.Update();
            }
        }

        public void open(String URL, String controls)
        {
            AdViewControl.OpenExternalUrl(URL);
        }

        public void resize(int width, int height)
        {
            _control.Size = new Size(width, height);
        }

        public void close()
        {
            if (_expandedControl != null)
            {
                _expandedControl.Stop();
                _control.Parent.Controls.Remove( _expandedControl );
                _expandedControl = null;
            }
            else
            {
                _control.Size = _originalSize;
            }
        }

	    public void hide()
        {
            if (_expandedControl != null) _expandedControl.Visible = false;
	        _control.Visible = false;
	    }

	    public void show()
        {
            if (_expandedControl != null) _expandedControl.Visible = true;
            _control.Visible = true;
        }

	    public String getMaxSize()
        {
            return "{\"width\":\"" + _control.Parent.Size.Width.ToString() + "\",\"height\":\"" + _control.Parent.Size.Height.ToString() + "\"}"; ;
        }

	    public String getSize()
        {
            return "{\"width\":\"" + _control.Size.Width.ToString() + "\",\"height\":\"" + _control.Size.Height.ToString() + "\"}"; ;
	    }

        public String getScreenSize()
        {
            return "{\"width\":\"" + SystemInformation.WorkingArea.Width.ToString() + "\",\"height\":\"" + SystemInformation.WorkingArea.Height.ToString() + "\"}"; ;
        }

        public bool supports(String feature)
        {
            if (String.Compare(feature,"level-1", true ) == 0)
	            return true;

            if (String.Compare(feature, "email", true) == 0)
                return true;

            if (String.Compare(feature, "calendar", true) == 0)
                return true;

            return false;
        }

        #endregion

        #region "Level-2 methods"
        public void storePicture( String url )
        {
            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Title = "Save file as...";
            //dialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
            dialog.RestoreDirectory = true;

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                WebClient Client = new WebClient();
                Client.DownloadFile(url, dialog.FileName);
            }            
        }


        public void createEvent( String date, String title, String body )
        {
            Microsoft.Office.Interop.Outlook.Application outlookApp = new Microsoft.Office.Interop.Outlook.Application(); // creates new outlook app
            Microsoft.Office.Interop.Outlook.AppointmentItem oAppointment = (Microsoft.Office.Interop.Outlook.AppointmentItem)outlookApp.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem);

            oAppointment.Subject = title;
            oAppointment.Body = body;
            oAppointment.Location = "Nicks Desk!";
            oAppointment.Start = Convert.ToDateTime(date);
            oAppointment.End = Convert.ToDateTime(date);
            oAppointment.ReminderSet = true;
            oAppointment.ReminderMinutesBeforeStart = 15;
            oAppointment.Importance = Microsoft.Office.Interop.Outlook.OlImportance.olImportanceHigh;
            oAppointment.BusyStatus = Microsoft.Office.Interop.Outlook.OlBusyStatus.olBusy;
            
            oAppointment.Save();
        }

        public void sendMail(String recipient, String subject, String body)
        {
            Process.Start("mailto:" + recipient + "?subject=" + subject + "&body=" + body);
        }
        #endregion

        #region "Level-3 methods"
        public void addAsset(String url, String alias)
        {
            _assetUrl = url;
            _assetAlias = alias;
            Thread _assetThread = new Thread(assetThreadProc);
            _assetThread.Start();

        }

        public void addAssets(String assets)
        {
            String [] array = getJsonStrings(assets);

            for (int f = 0; f < array.Length; f+=2 )
            {
                addAsset( array[f], array[f+1]);
            }
        }

        public String getAssetURL(String alias)
        {
            String s =  "file:///"+ Path.Combine(GetAssetsPath(), alias);
            s = s.Replace("\\", "/");

            return s;
        }
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
        out ulong lpFreeBytesAvailable,
        out ulong lpTotalNumberOfBytes,
        out ulong lpTotalNumberOfFreeBytes);

        public int getCacheRemaining()
        {
            string path =
                Path.GetPathRoot(
                    Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase));

            ulong FreeBytesAvailable;
            ulong TotalNumberOfBytes;
            ulong TotalNumberOfFreeBytes;

            bool success = GetDiskFreeSpaceEx(path, out FreeBytesAvailable, out TotalNumberOfBytes,
                               out TotalNumberOfFreeBytes);

            return Convert.ToInt32(FreeBytesAvailable);
        }

        public void RemoveAllAssets()
        {
            String[] files = Directory.GetFiles(GetAssetsPath(), "*.*");

            foreach (string s in files)
            {
                Thread _assetThread = new Thread( removeAssetThreadProc );
                _assetThread.Start(s);
            }
        }

        public void RemoveAsset(String alias)
        {
            String s = Path.Combine( GetAssetsPath(), alias );

            Thread _assetThread = new Thread( removeAssetThreadProc );
            _assetThread.Start(s);

        }

        public bool request(String val, String prx )
        {
            Thread _requestThread = new Thread(requestThreadProc);
            _requestThread.Start(val);

            return true;
        }

        private void requestThreadProc(object s)
        {
            try
            {
                s = "http://www.google.com";
                WebClient Client = new WebClient();
                String res = Client.DownloadString((String)s);

                if (_control != null)
                    _control.InvokeScript("_fireOrmmaRequest", res );
            }
            catch
            {
            }

        }


        private String GetAssetsPath()
        {
            String path = Path.Combine(AdViewControl.GetCachePath(), "Assets");
            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
            return Path.Combine(AdViewControl.GetCachePath(), "Assets");
        }

        private void removeAssetThreadProc(object s)
        {
            try
            {
                File.Delete((String)s);

                String alias = Path.GetFileName((String) s);

                if (_control != null)
                    _control.InvokeScript("_fireOrmmaAssetRemoved", alias );
            }
            catch
            {
            }

        }

        private void assetThreadProc()
        {
            try
            {
                if (String.Compare("ormma://screenshot", _assetUrl, true) == 0)
                {
                    SaveControlShot(AdViewControl.GetAppForm(_control.Handle), Path.Combine(GetAssetsPath(), _assetAlias), ImageFormat.Png);
                }
                else
                {
                    WebClient Client = new WebClient();
                    Client.DownloadFile(_assetUrl, Path.Combine(GetAssetsPath(), _assetAlias));

                    if (_control != null)
                        _control.InvokeScript("_fireOrmmaAssetReady", _assetAlias);
                }
            }
            catch
            {
            }

        }

        /// <summary>
        /// Saves a screen capture of the specified control to a file.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="filename"></param>
        /// <param name="format"></param>
        private void SaveControlShot(Control control, string filename, ImageFormat format)
        {
            Bitmap controlShot = CaptureControlShot(control);

            controlShot.Save(filename, format);
        }

        /// <summary>
        /// Gets a bitmap image of the specified control.
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        private Bitmap CaptureControlShot(Control control)
        {
            // get control bounding rectangle
            Rectangle bounds = control.Bounds;

            // create the new bitmap that holds the image of the control
            Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);

            // copy controls image data to the bitmaps graphics device
            using (Graphics gr = Graphics.FromImage(bitmap))
            {
                gr.CopyFromScreen(control.Location, Point.Empty, bounds.Size);
            }

            return bitmap;
        }
        #endregion
    }

}
